
const iRules = {
    phone(value: any) {
        const reg = /^1(\d){10}$/;
        return reg.test(value);
    },
    float(value: string | number, place: number = 2) {
        const reg = new RegExp(`(^[1-9]([0-9]+)?(.[0-9]{1,${place}})?$)|(^(0){1}$)|(^[0-9].([0-9]){1,${place}}?$)`);
        return reg.test(value.toString());
    },
    emall(value: any) {
        const reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
        return reg.test(value);
    },
    integer(value: any) {
        if (!Number.isInteger(parseFloat(value))) {
            return false;
        }
        return true;
    },
    require(value: any) {
        if (typeof value === "undefined" || value === null || value === "") {
            return false;
        }
        return true;
    },
}

declare type Rule = keyof typeof iRules;

export default class ValiDateUtils {
    private static instance: ValiDateUtils;
    public static getInstance() {
        if (!this.instance) {
            this.instance = new ValiDateUtils();
        }
        return this.instance;
    }

    /**
     * 校验规则
     * @param rules 
     */
    public rules(rules: RuleItem<Rule>[]) {
        return new ValiDate(rules);
    }
}


class ValiDate {
    private rules: RuleItem<Rule>[];
    public constructor(rules: RuleItem<Rule>[]) {
        this.rules = rules;
    }

    /**
     * 设置数据
     * @param data 
     */
    public validate(data: { [key: string]: any }) {
        for (let i = 0, len = this.rules.length; i < len; i++) {
            const item = this.rules[i];
            const key = item.key;
            const value = data[key];
            let result;
            if (typeof item.rule === 'function') {
                result = item.rule(value);
            } else if (item.rule instanceof RegExp) {
                result = item.rule.test(value);
            } else {
                result = iRules[item.rule](value, item.place);
            }

            if (!result) {
                return {
                    status: false,
                    key: item.key,
                    errMsg: item.msg || ''
                }
            }
        }
        return {
            status: true,
            errMsg: ''
        }
    }

}


interface RuleItem<T> {
    key: string,
    rule: ((value: any) => boolean) | RegExp | T,
    msg?: string,
    place?: number
}